package com.sinszm.es;

import cn.hutool.extra.spring.SpringUtil;
import com.sinszm.common.exception.ApiException;
import com.sinszm.es.dao.EsDao;
import com.sinszm.es.dao.Page;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.index.query.QueryBuilder;

import java.util.List;

/**
 * Es调用工具
 *
 * @author sinszm
 */
public final class EsUtil {

    /**
     * 判断实例是否存在
     *
     * @return      响应实例对象
     */
    private static EsDao dao(){
        final String name = "esDao";
        if (SpringUtil.getApplicationContext().containsBeanDefinition(name)) {
            return SpringUtil.getBean(EsDao.class);
        }
        throw new ApiException("未启用Es服务");
    }

    /**
     * 客户端
     *
     * @return  操作客户端
     */
    public static RestHighLevelClient es() {
        return dao().es();
    }

    /**
     * 判断索引是否存在
     * @param index     索引名称
     * @return          是否存在，true存在，false不存在
     */
    public static boolean existsIndex(String index) {
        return dao().existsIndex(index);
    }

    /**
     * 判断索引是否存在
     * @param tClass    索引类
     * @param <T>       泛型
     * @return          是否存在，true存在，false不存在
     */
    public static <T> boolean existsIndex(Class<T> tClass) {
        return dao().existsIndex(tClass);
    }

    /**
     * 创建索引
     * @param tClass        索引类
     * @param <T>           泛型
     * @return              创建结果
     */
    public static <T> CreateIndexResponse createIndex(Class<T> tClass) {
        return dao().createIndex(tClass);
    }

    /**
     * 删除索引
     * @param tClass            索引类
     * @param <T>               泛型
     * @return                  删除结果
     */
    public static <T> AcknowledgedResponse deleteIndex(Class<T> tClass) {
        return dao().deleteIndex(tClass);
    }

    /**
     * 插入索引数据
     * @param data              数据
     * @param create            是否创建索引结构
     * @param <T>               泛型
     * @return                  插入结果
     */
    public static <T> IndexResponse insert(T data, boolean create) {
        return dao().insert(data, create);
    }

    /**
     * 插入索引数据
     * <p>
     *     不执行索引结构的初始化创建
     * </p>
     * @param data              数据
     * @param <T>               泛型
     * @return                  插入结果
     */
    public static <T> IndexResponse insert(T data) {
        return dao().insert(data);
    }

    /**
     * 插入索引数据
     * <p>
     *     如果索引结构不存在则创建，如果索引存在则先删除结构再创建
     * </p>
     * @param data              数据
     * @param <T>               泛型
     * @return                  插入结果
     */
    public static <T> IndexResponse insertEs(T data) {
        return dao().insertEs(data);
    }

    /**
     * 更新索引数据
     * @param data              数据
     * @param <T>               泛型
     * @return                  更新结果
     */
    public static <T> UpdateResponse update(T data){
        return dao().update(data);
    }

    /**
     * 删除索引数据
     * @param data              数据
     * @param <T>               泛型
     * @return                  删除结果
     */
    public static <T> DeleteResponse delete(T data) {
        return dao().delete(data);
    }

    /**
     * 查询单条索引数据详情
     * @param id            索引ID
     * @param tClass        实体
     * @param <T>           泛型
     * @return              数据
     */
    public static <T> T findOne(String id, Class<T> tClass) {
        return dao().findOne(id, tClass);
    }

    /**
     * 查询全部
     * @param tClass        实体类
     * @param <T>           泛型
     * @return              索引列表
     */
    public static <T> List<T> findAll(Class<T> tClass) {
        return dao().findAll(tClass);
    }

    /**
     * 查询全部
     * @param tClass    实体类
     * @param size      游标每页返回数
     * @param <T>       泛型
     * @return          索引列表
     */
    public static <T> Page<T> findAll(Class<T> tClass, int size) {
        return dao().findAll(tClass, size);
    }

    /**
     * 查询数据
     * @param queryBuilder  查询条件
     * @param tClass        实体类
     * @param <T>           泛型
     * @return              按条件查询的数据列表
     */
    public static <T> List<T> query(QueryBuilder queryBuilder, Class<T> tClass) {
        return dao().query(queryBuilder, tClass);
    }

    /**
     * 按Scroll查询数据
     * @param queryBuilder  查询条件
     * @param size          每次scroll返回数据条数
     * @param tClass        实体类
     * @param <T>           泛型
     * @return              分页数据
     */
    public static <T> Page<T> query(QueryBuilder queryBuilder, int size, Class<T> tClass) {
        return dao().query(queryBuilder, size, tClass);
    }

}
